package com.beyond.generate.service.impl;


import com.beyond.generate.dao.SysGeneratorDao;
import com.beyond.generate.dao.SysOracleGeneratorDao;
import com.beyond.generate.entity.def.ColumnTable;
import com.beyond.generate.entity.def.ColumnType;
import com.beyond.generate.entity.ResultMap;
import com.beyond.generate.service.SysGeneratorService;
import com.beyond.generate.utils.Constant;
import com.beyond.generate.utils.GenUtils;
import com.beyond.generate.utils.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 代码生成器
 *
 * @author zhangyan
 */
public class SysGeneratorServiceImpl implements SysGeneratorService {

    private static SqlSession session;

    static {
        InputStream inputStream = null;
        try {
            inputStream = SysGeneratorServiceImpl.class.getClassLoader().getResourceAsStream("\\config\\mybatis-config.xml");
            if (Objects.isNull(inputStream)) {
                inputStream = SysGeneratorServiceImpl.class.getClassLoader().getResourceAsStream("config/mybatis-config.xml");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        session = sqlSessionFactory.openSession();
    }

    private SysGeneratorDao sysGeneratorDao;

    private SysOracleGeneratorDao sysOracleGeneratorDao;

    @Override
    public List<Map<String, Object>> queryList(Map<String, Object> map) {
        if ("ORACLE".equals(Constant.USE_DATA)) {
            sysOracleGeneratorDao = session.getMapper(SysOracleGeneratorDao.class);
            List<Map<String, Object>> list = sysOracleGeneratorDao.queryList(map);

            //oracle需转为驼峰命名
            List<Map<String, Object>> mapList = new ArrayList<Map<String, Object>>();
            for (Map<String, Object> stringObjectMap : list) {
                Map<String, Object> objectMap = new HashMap<String, Object>();
                for (String key : stringObjectMap.keySet()) {
                    String mapKey = StringUtil.lineToHump(key);
                    objectMap.put(mapKey, stringObjectMap.get(key));
                }
                mapList.add(objectMap);
            }
            return mapList;
        }
        sysGeneratorDao = session.getMapper(SysGeneratorDao.class);
        return sysGeneratorDao.queryList(map);
    }

    @Override
    public int queryTotal(Map<String, Object> map) {
        if ("ORACLE".equals(Constant.USE_DATA)) {
            sysOracleGeneratorDao = session.getMapper(SysOracleGeneratorDao.class);
            return sysOracleGeneratorDao.queryTotal(map);
        }
        sysGeneratorDao = session.getMapper(SysGeneratorDao.class);
        return sysGeneratorDao.queryTotal(map);
    }

    @Override
    public Map<String, String> queryTable(String tableName) {
        if ("ORACLE".equals(Constant.USE_DATA)) {
            sysOracleGeneratorDao = session.getMapper(SysOracleGeneratorDao.class);
            Map<String, String> objectMap = sysOracleGeneratorDao.queryTable(tableName);
            //oracle需转为驼峰命名
            Map<String, String> map = new HashMap<String, String>();
            for (String key : objectMap.keySet()) {
                String mapKey = StringUtil.lineToHump(key);
                map.put(mapKey, objectMap.get(key));
            }
            return map;
        }
        sysGeneratorDao = session.getMapper(SysGeneratorDao.class);
        return sysGeneratorDao.queryTable(tableName);
    }

    @Override
    public List<Map<String, String>> queryColumns(String tableName) {
        if ("ORACLE".equals(Constant.USE_DATA)) {
            sysOracleGeneratorDao = session.getMapper(SysOracleGeneratorDao.class);
            List<ResultMap> list = sysOracleGeneratorDao.queryColumns(tableName);
            //oracle
            List<Map<String, String>> mapList = new ArrayList<>();
            for (ResultMap stringObjectMap : list) {
                // 获取实体类的所有属性，返回Field数组
                Field[] field = stringObjectMap.getClass().getDeclaredFields();

                Map<String, String> objectMap = new HashMap<String, String>();
                for (int j = 0; j < field.length; j++) {
                    // 获取属性的名字
                    String name = field[j].getName();
                    // 将属性的首字符大写，方便构造get，set方法
                    String Name = name.substring(0, 1).toUpperCase() + name.substring(1);

                    try {
                        Method m = stringObjectMap.getClass().getMethod("get" + Name);
                        // 调用getter方法获取属性值
                        String value = (String) m.invoke(stringObjectMap);
                        objectMap.put(name, value);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                mapList.add(objectMap);
            }
            return mapList;
        }
        sysGeneratorDao = session.getMapper(SysGeneratorDao.class);
        return sysGeneratorDao.queryColumns(tableName);
    }

    @Override
    public void generatorCode(String[] tableNames) {
        System.out.println("*******************开始生成文件****************************");
        for (String tableName : tableNames) {
            //查询表信息
            Map<String, String> table = queryTable(tableName);
            //查询列信息
            List<Map<String, String>> columns = queryColumns(tableName);
            //将dataType转为大写
            for (Map<String, String> column : columns) {
                for (String str : column.keySet()) {
                    if (StringUtils.equals(str, "dataType")) {
                        if (org.apache.commons.lang3.StringUtils.equalsIgnoreCase(column.get(str), "int")) {
                            column.put(str, "Integer");
                        }
                        if (StringUtils.equalsIgnoreCase(column.get(str), "datetime")) {
                            column.put(str, "timestamp");
                        }
                        column.put(str, column.get(str).toUpperCase());
                    }
                }
            }
            //生成代码
            GenUtils.generatorCode(table, columns);
        }
        System.out.println("*******************执行完毕****************************");
    }


    @Override
    public List<ColumnType> queryColumnType(Map<String, Object> paramsMap) {

        sysGeneratorDao = session.getMapper(SysGeneratorDao.class);
        List<ColumnType> types = sysGeneratorDao.queryColumnType(paramsMap);
        return types;
    }

    @Override
    public Map<String, String> queryTableColumn() {
        Map<String, String> map = new HashMap<>();
        sysGeneratorDao = session.getMapper(SysGeneratorDao.class);
        List<ColumnTable> mapList = sysGeneratorDao.queryTableColumnType();
        map = mapList.stream().collect(Collectors.toMap(ColumnTable::getTableName, ColumnTable::getTableComment));
        return map;
    }

}
